package com.aube.interact;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.aube.interact.controller.BezierAnimHelper;
import com.aube.interact.model.GoodsItem;
import com.aube.interact.model.GoodsModel;
import com.aube.interact.model.ImageItem;
import com.aube.rvi.CommonDataLoader;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created by huyaonan on 16/3/21.
 */
public class GoodsHotpotLayout extends FrameLayout implements CardGoods.IAnimToCart {

    private Context mContext;

    private IAddFavorListener iAddFavorListener;

    private String mVideoId;

    public GoodsHotpotLayout(Context context) {
        this(context, null);
    }
    public GoodsHotpotLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public GoodsHotpotLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if(mGoods != null) {
//            int top = (getHeight() - mGoods.getMeasuredHeight())/2;
//            int left = getWidth() - 100 - mGoods.getMeasuredWidth();
////            mGoods.layout(mHotpotX + 100, top, mHotpotX + 100 + mGoods.getMeasuredWidth(), mGoods.getMeasuredHeight() + top);
//            mGoods.layout(left, top, left + mGoods.getMeasuredWidth(), mGoods.getMeasuredHeight() + top);
            int width = mGoods.getMeasuredWidth();
            int height = mGoods.getMeasuredHeight();

            if(mDetailX < 0)
                mDetailX = 0;
            if(mDetailX + width > getWidth())
                mDetailX = getWidth()-width;

            if(mDetailY < 0)
                mDetailY = 0;
            if(mDetailY + height > getHeight())
                mDetailY = getHeight() - height;

            mGoods.layout(mDetailX, mDetailY, mDetailX+width, mDetailY+height);
        }

        if(mImgView != null) {
            mImgView.layout(mImgX, mImgY, mImgX + mImgView.getMeasuredWidth(), mImgY + mImgView.getMeasuredHeight());
        }

        if(mHotpotView != null && mGoodsHotpotVisible) {
            mHotpotView.layout(mHotpotX, mHotpotY, mHotpotX + mHotpotView.getMeasuredWidth(), mHotpotY + mHotpotView.getMeasuredHeight());
        }
    }

    public void bindVideo(String mVideoId) {
        this.mVideoId = mVideoId;
    }

    private GoodsModel mData;

    private int mDetailX = 0;
    private int mDetailY = 0;

    private ImageItem mMiddleSizeHotpot = null;
    private int mHotpotX=0, mHotpotY=0;
    private int mHotpotW=0, mHotpotH=0;
    private GoodsHotpotView mHotpotView;
    public void showHotpot(GoodsModel data, final IAddFavorListener listener) {
        int width = getWidth();
        int height = getHeight();
        if(mMiddleSizeHotpot == null) {
            int GAP = (int) ((1 - 0.66f - 0.247f) * width / 3);

            int mWidth = (int) (width * 0.66f);
            int mHeight = (int) (width * 0.66 * 9 / 16);

            mMiddleSizeHotpot = new ImageItem(mWidth, mHeight, GAP, (height - mHeight) / 2);
        }

        if(mGoodsHotpotFullscreen) {
            mHotpotX = mHotpotY = 0;
            mHotpotW = width;
            mHotpotH = getHeight();
        } else {
            mHotpotX = mMiddleSizeHotpot.x;
            mHotpotY = mMiddleSizeHotpot.y;
            mHotpotW = mMiddleSizeHotpot.width;
            mHotpotH = mMiddleSizeHotpot.height;
        }

        this.mData = data;
        this.iAddFavorListener = listener;
        LayoutParams params = mGoodsHotpotFullscreen ? new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
                                                    : new LayoutParams(mMiddleSizeHotpot.width, mMiddleSizeHotpot.height);
        if(mHotpotView != null && mHotpotView.getParent() != null)
            removeView(mHotpotView);
        mHotpotView = new GoodsHotpotView(getContext());
        mHotpotView.setProgressListener(new GoodsHotpotView.IProgressListener() {
            @Override
            public int getCurrentProgress() {
                if(listener != null)
                    return listener.getProgress();
                return 0;
            }
        }, data.circleTrajectoryList);
        addView(mHotpotView, params);

        mHotpotView.setVisibility(mGoodsHotpotVisible ? VISIBLE : GONE);

        mHotpotView.setOnHotpotClickListener(new GoodsHotpotView.OnHotpotClickListener() {
            @Override
            public void onClick(int x, int y) {
                registerListener(listener, x, y);
            }
        });
    }

    private CardGoods mGoods;
    private AtomicBoolean mAnimatingGoods = new AtomicBoolean(false);

    public void hideGoods() {
        fadeOutCard();
    }

    private static final int FADE_DURATION = 150;
    private void fadeInCard(final int startX, final int startY, final int endX, final int endY) {
        if(mAnimatingGoods.get())
            return;
        mAnimatingGoods.set(true);
        mGoods.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        int width = mGoods.getMeasuredWidth();
        int height = mGoods.getMeasuredHeight();
        if(width == 0 || height == 0) {
            mGoods.setPivotX(0.5f);
            mGoods.setPivotY(0.5f);

            mDetailX = endX;
            mDetailY = endY;

            ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float fraction = (float) animation.getAnimatedValue();
                    mGoods.setAlpha(fraction);

                    mGoods.setScaleX(fraction);
                    mGoods.setScaleY(fraction);
                }
            });
            anim.setDuration(FADE_DURATION);
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mAnimatingGoods.set(false);
                }
            });
            anim.start();
        } else {
            mGoods.setPivotX(0.5f);
            mGoods.setPivotY(0.5f);

            mDetailX = startX;
            mDetailY = startY;

            ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float fraction = (float) animation.getAnimatedValue();
                    mGoods.setAlpha(fraction);

                    mGoods.setScaleX(fraction);
                    mGoods.setScaleY(fraction);

                    mDetailX = (int) (startX + (endX-startX)*fraction);
                    mDetailY = (int) (startY + (endY-startY)*fraction);

                    requestLayout();
                }
            });
            anim.setDuration(FADE_DURATION);
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mAnimatingGoods.set(false);
                }
            });
            anim.start();
        }
    }

    private void fadeOutCard() {
        if(mAnimatingGoods.get()) {
            //防止mAnimating卡死
            postDelayed(new Runnable() {
                @Override
                public void run() {
                    mAnimatingGoods.set(false);
                    fadeOutCard();
                }
            }, 300);
            return;
        }
        mAnimatingGoods.set(true);

        if(mGoods == null)
            return;

        final ValueAnimator anim = ValueAnimator.ofFloat(1, 0);
        anim.setDuration(FADE_DURATION);

        mGoods.setPivotX(0.5f);
        mGoods.setPivotY(0.5f);

        final int x = mDetailX;
        final int y = mDetailY;
        final int endx = mDetailX + mGoods.getWidth()/2;
        final int endy = mDetailY + mGoods.getHeight()/2;
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float fraction = (float) animation.getAnimatedValue();
                mGoods.setAlpha(fraction);

                mGoods.setScaleX(fraction);
                mGoods.setScaleY(fraction);

                mDetailX = (int) (x + (endx - x) * (1 - fraction));
                mDetailY = (int) (y + (endy - y) * (1 - fraction));

                requestLayout();
            }
        });
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                removeView(mGoods);
                mGoods = null;
                mAnimatingGoods.set(false);
            }
        });
        anim.start();
    }

    /**
     * 注册收藏事件
     * @param listener
     */
    public void registerListener(final IAddFavorListener listener, int startX, int startY) {
        if(listener == null)
            return;

        float[] pos = listener.getCardPosition();
        if(pos == null || pos.length != 2)
            return;
//        mDetailX = (int) (getWidth()*pos[0]);
//        mDetailY = (int) (getHeight()*pos[1]);

        if(mGoods != null) {
            hideGoods();
            return;
        }
        mGoods = new CardGoods(getContext());
        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        addView(mGoods, params);

        mGoods.setAlpha(0);

        mGoods.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                hideGoods();
            }
        });

        listener.hideFavorCart();

        mGoods.init(mData, listener, this);
        fadeInCard(startX, startY, (int) (getWidth()*pos[0]), (int) (getHeight()*pos[1]));
    }

    public boolean goodsViewRemoveable() {
        if(mGoods != null) {
            hideGoods();
            return true;
        }
        return false;
    }

    public void onDestroy() {
        //不移除物品
//        goodsViewRemoveable();

        if(mHotpotView != null) {
//            removeView(mHotpotView);
//            mHotpotView = null;
            mHotpotView.setVisibility(GONE);
        }
    }

    private ImageView mImgView;
    private int mImgX, mImgY;

    /**
     * 做商品的贝赛尔曲线动画
     * @param x
     * @param y
     * @param width
     * @param height
     * @param url
     */
    @Override
    public void anim(float x, float y, int width, int height, String url) {
        if(iAddFavorListener == null)
            return;
        int[] targetLocation = iAddFavorListener.getCartLocation();
        if(targetLocation == null)
            return;
        BezierAnimHelper.Point p1 = new BezierAnimHelper.Point(x, y, width, height);
        BezierAnimHelper.Point p2 = new BezierAnimHelper.Point(0, 0, width/2, height/2);
        BezierAnimHelper.Point p3 = new BezierAnimHelper.Point(targetLocation[0], targetLocation[1], 1, 1);
        BezierAnimHelper helper = new BezierAnimHelper();

        mImgView = new ImageView(mContext);
        mImgView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        LayoutParams params = new LayoutParams(width, height);
        addView(mImgView, params);
        CommonDataLoader.getInstance(getContext()).startImageLoader(mImgView, url, 200, 200);
        mImgX = (int) x;
        mImgY = (int) y;

        //往左上角缩小
        mImgView.setPivotX(0);
        mImgView.setPivotX(0);

        requestLayout();

        helper.startBezierAnim(new BezierAnimHelper.IAnimFeedBack() {
            @Override
            public void executeAnim(BezierAnimHelper.Point point, float fraction) {
                mImgView.setScaleX(1-fraction);
                mImgView.setScaleY(1 - fraction);

                mImgX = point.x;
                mImgY = point.y;

                requestLayout();
            }

            @Override
            public void animEnd() {
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if(mImgView != null)
                            removeView(mImgView);
                        mImgView = null;
                    }
                }, 100);
            }
        }, p1, p2, p3);
    }

    private boolean mGoodsHotpotFullscreen = true;
    private boolean mGoodsHotpotVisible = true;

    /**
     * 随着多镜头主屏幕切换尺寸
     * @param fullscreen
     */
    public void switchSize(boolean fullscreen) {
        mGoodsHotpotFullscreen = fullscreen;
        if(mHotpotView != null && mMiddleSizeHotpot != null) {
            ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
            anim.setDuration(300);
            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float value = (float) animation.getAnimatedValue();

                    ViewGroup.LayoutParams param = mHotpotView.getLayoutParams();
                    if(mGoodsHotpotFullscreen) {
                        param.width = (int) (mMiddleSizeHotpot.width + (getWidth()-mMiddleSizeHotpot.width)*value);
                        param.height = (int) (mMiddleSizeHotpot.height + (getHeight()-mMiddleSizeHotpot.height)*value);
                        mHotpotX = (int) (mMiddleSizeHotpot.x*(1-value));
                        mHotpotY = (int) (mMiddleSizeHotpot.y*(1-value));
                    } else {
                        param.width = (int) (mMiddleSizeHotpot.width + (getWidth()-mMiddleSizeHotpot.width)*(1-value));
                        param.height = (int) (mMiddleSizeHotpot.height + (getHeight()-mMiddleSizeHotpot.height)*(1-value));
                        mHotpotX = (int) (mMiddleSizeHotpot.x*(value));
                        mHotpotY = (int) (mMiddleSizeHotpot.y*(value));
                    }
                    mHotpotView.setLayoutParams(param);
                    requestLayout();
                }
            });
            anim.start();
        }
    }

    /**
     * 是否展示热点
     * @param display
     */
    public void diaplayHotpot(boolean display) {
        mGoodsHotpotVisible = display;
        if(mHotpotView != null)
            mHotpotView.setVisibility(display ? VISIBLE : GONE);
    }

    public interface IAddFavorListener {
        public void doFavorEvent(GoodsItem item);
        public void cancelFavor(String id);
        public int[] getCartLocation();
        public float[] getCardPosition();
        public int getProgress();
        public void hideFavorCart();
    }

}
